package alarmUDP

import (
	"bytes"
	"encoding/json"
	"fmt"
	"gitee.com/tsingeye/FreeEhome/tools"
	"net"
	"net/http"
	"strconv"
	"strings"
	"time"

	"gitee.com/tsingeye/FreeEhome/config"
	"gitee.com/tsingeye/FreeEhome/tools/logs"
	"github.com/tinyhubs/tinydom"
)

var calcTransform = func(v int64) float64 {
	_du := int64(v / 3600 / 100)
	_fen := int64((v - _du*3600*100) / 100 / 60)
	_miao := int64((v - _du*3600*100 - _fen*60*100) / 100)
	_latlon := float64(_du) + float64(_fen)/60 + float64(_miao)/60/60

	return _latlon
}

//启动报警UDP服务器
func ListenAlarmUDPServer() {
	//创建udp地址
	udpAddr, err := net.ResolveUDPAddr("udp", config.EHomeAlarmUDPAddr)
	if err != nil {
		fmt.Printf("%s ListenAlarmUDPServer() ---> net.ResolveUDPAddr() error:%s\n", time.Now().Format(config.TimeLayout), err)
		logs.PanicLogger.Panicln(fmt.Sprintf("ListenAlarmUDPServer() ---> net.ResolveUDPAddr() error:%s", err))
	}

	//监听udp地址
	udpConn, err := net.ListenUDP("udp", udpAddr)
	if err != nil {
		fmt.Printf("%s ListenAlarmUDPServer() ---> net.ListenUDP() error:%s\n", time.Now().Format(config.TimeLayout), err)
		logs.PanicLogger.Panicln(fmt.Sprintf("ListenAlarmUDPServer() ---> net.ListenUDP() error:%s", err))
	}

	fmt.Printf("%s ListenAlarmUDPServer() ---> start EHome's alarmUDPServer successful!!!\n", time.Now().Format(config.TimeLayout))
	logs.BeeLogger.Emergency("ListenAlarmUDPServer() ---> start EHome's alarmUDPServer successful!!!")

	//延迟关闭监听
	defer udpConn.Close()
	for {
		buf := make([]byte, 2048)
		//阻塞获取数据
		n, _, err := udpConn.ReadFromUDP(buf)
		if err != nil {
			logs.BeeLogger.Error("ListenAlarmUDPServer() ---> udpConn.ReadFromUDP() error:%s", err)
			return
		}

		logs.BeeLogger.Debug("ListenAlarmUDPServer() ---> receive raw data:%s", buf[:n])

		go eHomeAlarmForward(buf[:n])
	}
}

//报警信息转发
func eHomeAlarmForward(requestBody []byte) {
	client := &http.Client{
		Transport: &http.Transport{
			Dial: func(network, addr string) (net.Conn, error) {
				conn, err := net.DialTimeout(network, addr, time.Second*time.Duration(config.EHomeAlarmForwardTimeout)) //设置建立连接超时
				if err != nil {
					return nil, err
				}
				conn.SetDeadline(time.Now().Add(time.Second * time.Duration(config.EHomeAlarmForwardTimeout))) //设置发送接受数据超时
				return conn, nil
			},
			ResponseHeaderTimeout: time.Second * time.Duration(config.EHomeAlarmForwardTimeout),
		},
	}
	utfBody, err := tools.GB2312ToUTF8(requestBody)
	if err != nil {
		return
	}
	doc, err := tinydom.LoadDocument(strings.NewReader(string(utfBody)))
	if err != nil {
		fmt.Println("load xml fail.")
		return
	}
	elem1 := doc.FirstChildElement("PPVSPMessage").FirstChildElement("Command")
	fmt.Println(elem1.Text())
	//非GPS暂不处理
	if elem1.Text() != "GPS" {
		return
	}
	params := doc.FirstChildElement("PPVSPMessage").FirstChildElement("Params")
	deviceID := params.FirstChildElement("DeviceID")
	time := params.FirstChildElement("Time")
	longitude := params.FirstChildElement("Longitude")
	latitude := params.FirstChildElement("Latitude")
	speed := params.FirstChildElement("Speed")
	height := params.FirstChildElement("Height")
	direction := params.FirstChildElement("Direction")
	fmt.Println(deviceID.Text(), time.Text(), longitude.Text(), latitude.Text(), speed.Text(), height.Text())

	longit, _ := strconv.ParseInt(longitude.Text(), 10, 64)
	latit, _ := strconv.ParseInt(latitude.Text(), 10, 64)

	userMap := make(map[string]string)
	userMap["DeviceID"] = deviceID.Text()
	userMap["Time"] = time.Text()
	userMap["Longitude"] = strconv.FormatFloat(calcTransform(longit), 'f', 6, 64)
	userMap["Latitude"] = strconv.FormatFloat(calcTransform(latit), 'f', 6, 64)
	userMap["Direction"] = direction.Text()
	userMap["Speed"] = speed.Text()
	userMap["Height"] = height.Text()

	b, err := json.Marshal(userMap)
	if err != nil {
		fmt.Println("error:", err)
	}
	request, err := http.NewRequest("POST", config.EHomeAlarmForwardRoute, bytes.NewReader(b))
	if err != nil {
		logs.BeeLogger.Error("eHomeAlarmForward() ---> http.NewRequest() error:%s", err)
		return
	}
	request.Header.Set("Content-Type", "application/json;charset=UTF-8")

	response, err := client.Do(request)
	if err != nil {
		logs.BeeLogger.Error("eHomeAlarmForward() ---> client.Do() error:%s", err)
		return
	}

	defer response.Body.Close()
}
